#include "gd32f30x.h"
#include "string.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "stdbool.h"
#include "Delay.h"
#include "stdio.h"
extern SemaphoreHandle_t Mutex_Handle;

uint8_t rxcnt;
uint8_t rxbuffer[256];
uint8_t usebuf[256];
volatile bool comeplete = true;
volatile bool rx_complete = false;
volatile uint32_t last_getRxbufTim = 0;
volatile uint32_t current_getRxbufTim = 0;

// static uint8_t i;

void Myusart_Init(void)
{
	rcu_periph_clock_enable(RCU_GPIOA);
	rcu_periph_clock_enable(RCU_USART0);
	rcu_periph_clock_enable(RCU_DMA0);

	dma_parameter_struct dma_init_struct;

	nvic_irq_enable(DMA0_Channel3_IRQn, 1, 1);
	// nvic_irq_enable(DMA0_Channel4_IRQn, 1, 2);
	nvic_irq_enable(USART0_IRQn, 1,2);

	gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);//tx
	gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);//rrx

	usart_deinit(USART0);
	usart_baudrate_set(USART0, 115200);
	usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
	usart_receive_config(USART0, USART_RECEIVE_ENABLE);
	usart_enable(USART0);

	usart_interrupt_enable(USART0, USART_INT_RBNE);

//tx
	dma_deinit(DMA0, DMA_CH3);
	dma_struct_para_init(&dma_init_struct);
	dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
//	dma_init_struct.memory_addr = (uint32_t)txbuff;发送数据函数里面设置
	dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
	dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
//	dma_init_struct.number = (uint32_t)(sizeof(txbuff) / sizeof(*(txbuff)));发送函数里面设置
	dma_init_struct.periph_addr = (uint32_t)&USART_DATA(USART0);
	dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
	dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
	dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
	dma_init(DMA0, DMA_CH3, &dma_init_struct);


	dma_circulation_disable(DMA0, DMA_CH3);
	dma_memory_to_memory_disable(DMA0, DMA_CH3);



	usart_dma_transmit_config(USART0, USART_TRANSMIT_DMA_ENABLE);
	dma_interrupt_enable(DMA0, DMA_CH3, DMA_INT_FTF);
	//dma_channel_enable(DMA0, DMA_CH3);	


}
void SendData(char *Data, uint8_t length)
{
	while(!comeplete);

	dma_memory_address_config(DMA0, DMA_CH3, (uint32_t)Data);
	dma_transfer_number_config(DMA0, DMA_CH3,length);

	comeplete = false;
	dma_channel_enable(DMA0, DMA_CH3);
}
void SendNum(uint8_t num)
{
	char buf[128];
	uint8_t length = sprintf(buf, "%d", num);
	if(length)
	{
		SendData(buf, length);
	}
}
//tx
void DMA0_Channel3_IRQHandler(void)
{
	if(dma_interrupt_flag_get(DMA0, DMA_CH3, DMA_INT_FLAG_FTF) == SET)
	{
		dma_interrupt_flag_clear(DMA0 , DMA_CH3, DMA_INT_FLAG_FTF);
		dma_channel_disable(DMA0, DMA_CH3);
		comeplete = true;
	}
}

// void USART0_IRQHandler(void)
// {
// 	if(usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE) == SET)
// 	{		
// 		if(rxcnt >= sizeof(rxbuffer)) rxcnt = 0;
// 		rxbuffer[rxcnt++] = usart_data_receive(USART0);		
// 		usart_interrupt_flag_clear(USART0, USART_INT_FLAG_RBNE);

// 		last_getRxbufTim = xTaskGetTickCountFromISR();//获取最后一次拿数据的时间
// 		rx_complete = true;
// 	}
// }
uint8_t GetRxData(uint8_t *buf, uint16_t max_len) 
{
    if(!rx_complete) return 0;

	current_getRxbufTim = xTaskGetTickCount();
	 if((current_getRxbufTim - last_getRxbufTim) > pdMS_TO_TICKS(500))//如果现在的时间距离上一次获取到的数据的时间大于50tick就代表
	 {																//串口中断数据接收完成，将他获取出来
		// 防止中断修改数据
		//__disable_irq();		
		uint16_t len = (rxcnt < max_len) ? rxcnt : max_len;
		rxcnt = 0;//rxbuf的计数清零
		memcpy(buf, rxbuffer, len);
		memset(rxbuffer, 0, 256);
		rx_complete = false; // 清除标志
		//__enable_irq();

		return len;
	 }
	 else
	 return 0;

}
 void Test_Rx(void)
{
	//BaseType_t rret = pdFALSE;
	uint8_t len = 0;	
	memset(usebuf, 0, sizeof(usebuf)); //清空usebuf 
	len = GetRxData(usebuf, sizeof(usebuf));//获取数据到usebuf里面
	if(len > 0)
	{
		SendData((char*)usebuf, strlen((const char *)usebuf));
		// rret = xSemaphoreTake(Mutex_Handle, pdMS_TO_TICKS(50));//获取互斥信号量来通过IIC操作oled
		// if(rret == pdTRUE)
		// {
		// 	i++;//每次获取到了信号量就+1
		// 	OLED_ShowString(3, 1, "ok");
		// 	OLED_ShowNum(3,5,i,2);
		// 	OLED_ShowString(4, 1, "                ");
		// 	OLED_ShowString(4, 1, (char*)usebuf);
		// 	xSemaphoreGive(Mutex_Handle);			
		// }
	}
}
// void Usart_receive_Task(void *parameter)
// {
// 	for(;;)
// 	{
// 		Test_Rx();
// 		vTaskDelay(20);
// 	}
// }